import { createApp } from 'vue'
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import 'element-plus/theme-chalk/dark/css-vars.css'
import { VueFlow } from '@vue-flow/core'
import '@vue-flow/core/dist/style.css'
import '@vue-flow/core/dist/theme-default.css'
import '@vue-flow/controls/dist/style.css'
import '@vue-flow/minimap/dist/style.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'

// Import Context Menu
import ContextMenu from '@imengyu/vue3-context-menu'
import '@imengyu/vue3-context-menu/lib/vue3-context-menu.css'

// Import Naive UI
import naive from 'naive-ui'

import App from './App.vue'
import router from './router'
import './utils/monacoWorkers'
import './assets/main.scss' // Restore main.scss import


// Import Toastification
import VueToast, { type PluginOptions, POSITION } from 'vue-toastification'
import 'vue-toastification/dist/index.css'

// Import libxml2-wasm input provider and registration function
import { xmlRegisterInputProvider } from 'libxml2-wasm';
import { webFetchInputProvider } from '@/utils/validationUtils'; // Adjust path if needed

// Import settings store for initial theme application
import { useSettingsStore } from './stores/settingsStore'; 

// Import Services
import { swcService } from '@/services/swcService';
import { quickJsService } from '@/services/quickjsService'; // <-- Import QuickJS service

// --- App Initialization --- 
async function initializeAndMount() {
    // Initialize services concurrently
    try {
        console.log("[Main] Initializing external services...");
        await Promise.all([
            swcService.initialize(),
            quickJsService.initialize() // <-- Initialize QuickJS
        ]);
        console.log("[Main] External services initialized.");
    } catch (error) {
        // Handle critical initialization failure 
        console.error("[Main] Service initialization failed critically:", error)
    }
    
    // --- Create App and Plugins (Moved inside async function) --- 
    const app = createApp(App)

    // Initialize Pinia
    const pinia = createPinia()
    pinia.use(piniaPluginPersistedstate)

    // Register libxml2 WASM module if needed
    // This might need to be conditional based on settings or browser support
    // Consider moving this registration to where libxml2 is actually used
    // console.log('[Main] Registering webFetchInputProvider for libxml2.');
    // registerLibxml(); // Assuming this might be the source of error, comment out for now if unsure

    // Register Element Plus Icons
    for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
        app.component(key, component)
    }

    // Toastification options
    const toastOptions: PluginOptions = {
        transition: "Vue-Toastification__fade",
        maxToasts: 10,
        newestOnTop: true,
        position: POSITION.TOP_RIGHT,
        timeout: 5000,
        closeOnClick: true,
        pauseOnFocusLoss: true,
        pauseOnHover: true,
        draggable: true,
        draggablePercent: 0.6,
        showCloseButtonOnHover: false,
        hideProgressBar: false,
        closeButton: "button",
        icon: true,
        rtl: false
    };

    // Use Plugins (Ensure app exists before using use)
    app.use(pinia)
    app.use(router)
    app.use(ElementPlus)
    app.use(VueToast, toastOptions); // Use VueToast here
    app.use(ContextMenu) // Register Context Menu
    app.use(naive) // Use Naive UI

    // Mount App
    app.mount('#app')

    console.log('[Main] App mounted.');

    // Global error handler (optional but recommended)
    app.config.errorHandler = (err, instance, info) => {
        console.error("[Vue warn]: Unhandled error during execution of ", info, err);
        // Optionally send error to a logging service
    }

    // Initial theme application (moved from App.vue for consistency)
    const settingsStore = useSettingsStore(pinia) // Pass pinia instance
    settingsStore.applyTheme()
}

// Execute the initialization and mounting function
initializeAndMount();